package com.woniu.listener;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rabbitmq.client.Channel;
import com.woniu.enumeration.OrderStatus;
import com.woniu.pojo.Item;
import com.woniu.pojo.Order;
import com.woniu.redis.RedisConst;
import com.woniu.service.ItemService;
import com.woniu.service.OrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * 监听超时未支付订单 （死信队列）
 *
 *
 * */
@Component
@RabbitListener(queues = "order.dead.queue")
@Slf4j
public class OrderStatusListener {
    @Autowired
    private OrderService orderService;
    @Autowired
    private ItemService itemService;
    @Autowired
    private RedisTemplate redisTemplate;
    @SneakyThrows
    @RabbitHandler
    public void handle(Order order, Message message, Channel channel,
                       @Header(AmqpHeaders.DELIVERY_TAG) Long deliveryTag) {
        log.info("订单超时未支付，订单号：{}", order.getOrderNum());
        // 1.根据订单id查询，得到订单对象
        Order dbOrder = orderService.getById(order.getId());
        // 2.判断订单状态，如果为1，超时未支付
        if (dbOrder.getState().equals(OrderStatus.NO_PAY.getCode())) {
            // 3.修改订单状态为7 已取消
            dbOrder.setState(OrderStatus.ALREADY_CANCEL.getCode());
            // 修改数据中订单状态 为已取消
            orderService.updateById(dbOrder);

            // 4.回退redis库存信息
            // 4.1查询db中该订单所有订单项商品信息
            LambdaQueryWrapper<Item> wrapper = Wrappers.lambdaQuery(Item.class)
                    .eq(Item::getOrderId, dbOrder.getId());
            itemService.list(wrapper).forEach(item -> {
                // 4.2回退redis库存信息
                redisTemplate.opsForHash().increment(
                        RedisConst.BOOK_STORAGE,
                        item.getBookId().toString(),
                        item.getBuyCount());
                log.info("回退redis库存信息，商品id：{}，回退数量：{}", item.getBookId(), item.getBuyCount());
                // 4.3 更新订单项状态
                item.setState(OrderStatus.ALREADY_CANCEL.getCode());
                // 4.4 更新数据库 订单项状态
                itemService.updateById(item);
            });
            log.info("订单超时未支付，已取消，订单号：{}", dbOrder.getOrderNum());
        }
        // 手动确认消息
        channel.basicAck(deliveryTag, false);
    }

}
